package com.szy.security.oauth;

import com.szy.system.api.result.Result;
import com.szy.system.api.result.ResultUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.provider.error.AbstractOAuth2SecurityExceptionHandler;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author : zhenyun.su
 * @comment : 无效Token异常处理，参考 :OAuth2AuthenticationEntryPoint
 * 可放入公共代码库中
 * @since : 2020/6/15
 */
@Deprecated
public class SzyTokenExceptionHandler extends AbstractOAuth2SecurityExceptionHandler implements AuthenticationEntryPoint {
    private String typeName = "Bearer";
    private String realmName = "oauth";

    public void setRealmName(String realmName) {
        this.realmName = realmName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        this.doHandle(request, response, authException);
    }
    @Override
    protected ResponseEntity<?> enhanceResponse(ResponseEntity<?> response, Exception exception) {
        HttpHeaders headers = response.getHeaders();
        String existing = null;
        if (headers.containsKey("WWW-Authenticate")) {
            existing = this.extractTypePrefix(headers.getFirst("WWW-Authenticate"));
        }

        Result<Object> result = ResultUtils.failure(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase(), exception.getMessage());

        StringBuilder builder = new StringBuilder();
        builder.append(this.typeName + " ");
        builder.append("realm=\"" + this.realmName + "\"");
        if (existing != null) {
            builder.append(", " + existing);
        }

        HttpHeaders update = new HttpHeaders();
        update.putAll(response.getHeaders());
        update.set("WWW-Authenticate", builder.toString());
        return new ResponseEntity(result, update, response.getStatusCode());
    }

    private String extractTypePrefix(String header) {
        String existing = header;
        String[] tokens = header.split(" +");
        if (tokens.length > 1 && !tokens[0].endsWith(",")) {
            existing = StringUtils.arrayToDelimitedString(tokens, " ").substring(header.indexOf(" ") + 1);
        }

        return existing;
    }

}
